﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ChinaDynastyTours.Controls;
using ChinaDynastyTours.Helpers;
using ChinaDynastyTours.Models;
using System.Threading;

namespace ChinaDynastyTours.Views
{
    public partial class FinanceSettlementForm : DevExpress.XtraEditors.XtraForm
    {
        private DataTable _dtExpense;
        private DataTable _dtIncomeItem;
        private DataTable _dtTourgroup;
        
        public FinanceSettlementForm()
        {
            InitializeComponent();
        }

        private void FinanceSettlementForm_Load(object sender, EventArgs e)
        {
            //初始化团下拉列表
            DataSet ds = TeamGroupCtrl.GetAllIDForTeamGroup();
            if (ds.Tables.Count > 0)
            {
                foreach (DataRow dr in ds.Tables[0].Rows)
                    btnTeamGroupID.Properties.Items.Add(dr["TourGroupID"].ToString().Trim());
            }

            FinanceStatistics();
        }

        //计算团总体财务状况
        private void FinanceStatistics()
        {
            if (string.IsNullOrEmpty(tbTourgroupState.Text) || string.IsNullOrEmpty(btnTeamGroupID.Text)) return;

            decimal dSaleTotalPrice, dSaleTotalCost, dPlanPriceTotal, dRealReceivedPriceTotal, dAdjustPriceTotal, dPlanBudgetTotal, dRealApplyPayTotal, dAdjustAmountTotal;

            DataTable dtSale = TeamGroupCtrl.GetTeamGroupRowData(btnTeamGroupID.Text);

            //switch (EnumHelper.Team_Str2Enum(tbTourgroupState.Text, false))
            //{
            //    case TeamStateEnum.计划:
            //    case TeamStateEnum.成行:
            //        dSaleTotalPrice = decimal.Parse(dtSale.Rows[0]["SaleTotalPrice"].ToString());                                               //销售价格
            //        dSaleTotalCost = decimal.Parse(dtSale.Rows[0]["SaleTotalCost"].ToString());                                                 //销售成本
                    
            //        tbSaleTotalPrice.EditValue = dSaleTotalPrice;                                                                               
            //        tbSaleTotalCost.EditValue = dSaleTotalCost;                                                                                 
            //        tbSaleMaori.EditValue = dSaleTotalPrice - dSaleTotalCost;                                                                   //销售毛利
            //        tbSaleMaoriRate.EditValue = dSaleTotalPrice == 0 ? 0 : (dSaleTotalPrice - dSaleTotalCost) / dSaleTotalPrice;                //销售毛利率
            //        break;
            //    case TeamStateEnum.审核:
            //    case TeamStateEnum.终结:
            if (dtSale.Rows.Count > 0)
            {
                dSaleTotalPrice = decimal.Parse(dtSale.Rows[0]["SaleTotalPrice"].ToString());
                dSaleTotalCost = decimal.Parse(dtSale.Rows[0]["SaleTotalCost"].ToString());
                dPlanPriceTotal = IncomeItemCtrl.GetIncomeItemPlanPriceTotal(btnTeamGroupID.Text);                                          //计划额收入
                dRealReceivedPriceTotal = IncomeItemCtrl.GetIncomeItemReceivedPriceTotal(btnTeamGroupID.Text);                              //实际额收入
                dAdjustPriceTotal = IncomeItemCtrl.GetIncomeItemAdjustPriceTotal(btnTeamGroupID.Text);                                      //收入调整值
                dPlanBudgetTotal = ExpensesCtrl.GetExpenseBudgetTotal(btnTeamGroupID.Text);                                                 //计划额成本
                dRealApplyPayTotal = ExpensesCtrl.GetExpenseApplyPayTotal(btnTeamGroupID.Text);                                             //实际额成本
                dAdjustAmountTotal = ExpensesCtrl.GetExpenseAdjustAmountTotal(btnTeamGroupID.Text);                                         //成本调整值

                tbSaleTotalPrice.EditValue = decimal.Parse(dtSale.Rows[0]["SaleTotalPrice"].ToString());                                    //销售价格
                tbSaleTotalCost.EditValue = decimal.Parse(dtSale.Rows[0]["SaleTotalCost"].ToString());                                      //销售成本
                tbSaleMaori.EditValue = dSaleTotalPrice - dSaleTotalCost;                                                                   //销售毛利
                tbSaleMaoriRate.EditValue = dSaleTotalPrice == 0 ? 0 : (dSaleTotalPrice - dSaleTotalCost) / dSaleTotalPrice;                //销售毛利率

                tbPlanPriceTotal.EditValue = dPlanPriceTotal;
                tbRealReceivedPriceTotal.EditValue = dRealReceivedPriceTotal;
                tbAdjustPriceTotal.EditValue = dAdjustPriceTotal;

                tbPlanMaori.EditValue = dPlanPriceTotal - dPlanBudgetTotal;                                                                         //计划毛利
                tbPlanMaoriRate.EditValue = dPlanPriceTotal == 0 ? 0 : (dPlanPriceTotal - dPlanBudgetTotal) / dPlanPriceTotal;                      //计划毛利率

                tbPlanBudgetTotal.EditValue = dPlanBudgetTotal;
                tbRealPayTotal.EditValue = dRealApplyPayTotal;
                tbAdjustAmountTotal.EditValue = dAdjustAmountTotal;

                tbRealMaori.EditValue = dRealReceivedPriceTotal - dRealApplyPayTotal;                                                                    //计划毛利
                tbRealMaoriRate.EditValue = dRealReceivedPriceTotal == 0 ? 0 : (dRealReceivedPriceTotal - dRealApplyPayTotal) / dRealReceivedPriceTotal; //计划毛利率
            }
            //        break;
            //    default:
            //        break;
            //}
        }
        private void btnTeamGroupID_TextChanged(object sender, EventArgs e)
        {
            _dtTourgroup = TeamGroupCtrl.GetTeamGroupRowData(btnTeamGroupID.Text);
            
            tbTourgroupName.DataBindings.Clear();
            tbTourgroupState.DataBindings.Clear();
            tbOwnerA.DataBindings.Clear();
            tbAdultNum.DataBindings.Clear();

            tbTourgroupName.DataBindings.Add("EditValue", _dtTourgroup, "TourgroupName");
            tbTourgroupState.DataBindings.Add("EditValue", _dtTourgroup, "TourgroupState");
            tbOwnerA.DataBindings.Add("EditValue", _dtTourgroup, "OwnerA");
            tbAdultNum.DataBindings.Add("EditValue", _dtTourgroup, "AdultNum");

            //团财务情况统计
            FinanceStatistics();
            //显示各项数据
            financeTab_SelectedPageChanged(financeTab, new DevExpress.XtraTab.TabPageChangedEventArgs(null,financeTab.SelectedTabPage));
        }

        private void financeTab_SelectedPageChanged(object sender, DevExpress.XtraTab.TabPageChangedEventArgs e)
        {
            switch (e.Page.Name)
            {
                case "IncomePage":
                    _dtIncomeItem = IncomeItemCtrl.GetIncomeItemData(btnTeamGroupID.Text);
                    _dtIncomeItem.ColumnChanged += new DataColumnChangeEventHandler(IncomeItem_ColumnChanged);
                    incomeItemGridControl.DataSource = _dtIncomeItem;

                    if (tbTourgroupState.Text == TeamStateEnum.终结.ToString())
                    {
                        incomeItemGridView.OptionsBehavior.Editable = false;
                    }
                    else
                    {
                        incomeItemGridView.OptionsBehavior.Editable = true;
                    }

                    if (incomeItemGridView.FocusedRowHandle < 0)
                        incomeGridControl.DataSource = null;
                    else
                    {
                        string incomeItemId = incomeItemGridView.GetRowCellValue(incomeItemGridView.FocusedRowHandle, "IncomeItemID").ToString();
                        incomeGridControl.DataSource = IncomeItemCtrl.GetIncomeData(incomeItemId);
                    }
                    break;
                case "PaymentPage":
                    _dtExpense = ExpensesCtrl.GetExpenseData(btnTeamGroupID.Text);
                    _dtExpense.ColumnChanged += new DataColumnChangeEventHandler(Expense_ColumnChanged);
                    expenseGridControl.DataSource = _dtExpense;

                    if (tbTourgroupState.Text == TeamStateEnum.终结.ToString())
                    {
                        expenseGridView.OptionsBehavior.Editable = false;
                        btnAddPayment.Enabled = false;
                    }
                    else
                    {
                        expenseGridView.OptionsBehavior.Editable = true;
                        btnAddPayment.Enabled = true;
                    }
                    if (expenseGridView.FocusedRowHandle < 0)
                    {
                        //好像只有这个标签页需要判断详情列表是否为空，收入的倒不用。大概和加载顺序有关系。
                        
                        if (payDetailGridControl != null)
                            payDetailGridControl.DataSource = null;
                    }
                    else
                    {
                        if (payDetailGridControl != null)
                        {
                            string expenseId = expenseGridView.GetRowCellValue(expenseGridView.FocusedRowHandle, "ExpenseID").ToString();
                            DataTable payDt = PayDetailCtrl.GetPayDetailDataByExpenseId(expenseId);
                            DataTable cashDt = CashDetailCtrl.GetCashDetailDataByExpenseID(expenseId);
                            payDetailGridControl.DataSource = (payDt != null && payDt.Rows.Count > 0) ? payDt : cashDt;//谁不为空显示谁(付款详情和报销详情)
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        void IncomeItem_ColumnChanged(object sender, DataColumnChangeEventArgs e)
        {
            //能够引发列更新的只有‘调整金额’列,因此可直接更新计划收入项“AdjustPrice调整金额”
            IncomeItemCtrl.UpdateIncomeItemAdjustPrice(e.Row["IncomeItemID"].ToString(), decimal.Parse(e.Row["AdjustPrice"].ToString()));
        }
        void Expense_ColumnChanged(object sender, DataColumnChangeEventArgs e)
        {
            //能够引发列更新的只有‘调整金额’列,因此可直接更新计划收入项“AdjustPrice调整金额”
            ExpensesCtrl.UpdateExpenseAdjustAmountData(decimal.Parse(e.Row["AdjustAmount"].ToString()), e.Row["ExpenseID"].ToString());
        }

        private void incomeItemGridView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            if (e.FocusedRowHandle < 0)
                incomeGridControl.DataSource = null;
            else
            {
                string incomeItemId = incomeItemGridView.GetRowCellValue(e.FocusedRowHandle, "IncomeItemID").ToString();
                incomeGridControl.DataSource = IncomeItemCtrl.GetIncomeData(incomeItemId);
            }
        }

        private void expenseGridView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            if (e.FocusedRowHandle < 0)
            {
                if (payDetailGridControl != null)
                    payDetailGridControl = null;
            }
            else
            {
                if (payDetailGridControl != null)
                {
                    string expenseId = expenseGridView.GetRowCellValue(e.FocusedRowHandle, "ExpenseID").ToString();
                    DataTable payDt = PayDetailCtrl.GetPayDetailDataByExpenseId(expenseId);
                    DataTable cashDt = CashDetailCtrl.GetCashDetailDataByExpenseID(expenseId);
                    payDetailGridControl.DataSource = (payDt != null && payDt.Rows.Count > 0) ? payDt : cashDt;//谁不为空显示谁(付款详情和报销详情)

                }
            }
        }

        //private void btnIncomeAdjustDiff_Click(object sender, EventArgs e)
        //{
            //if (incomeItemGridView.FocusedRowHandle < 0) return;

            //string incomeItemId = incomeItemGridView.GetRowCellValue(incomeItemGridView.FocusedRowHandle, "IncomeItemID").ToString();
            //decimal ReceivedPrice = decimal.Parse(incomeItemGridView.GetRowCellValue(incomeItemGridView.FocusedRowHandle, "ReceivedPrice").ToString());
            //decimal PlanPrice = decimal.Parse(incomeItemGridView.GetRowCellValue(incomeItemGridView.FocusedRowHandle, "PlanPrice").ToString());

            ////更新计划收入项“AdjustPrice调整金额”
            //IncomeItemCtrl.UpdateIncomeItemAdjustPrice(incomeItemId, ReceivedPrice - PlanPrice);
            ////更新界面
            //incomeItemGridView.SetRowCellValue(incomeItemGridView.FocusedRowHandle, "AdjustPrice", ReceivedPrice - PlanPrice);
        //}

        //private void btnPayAdjustDiff_Click(object sender, EventArgs e)
        //{
            //if (payDetailGridView.FocusedRowHandle < 0) return;
            //string expenseId = payDetailGridView.GetRowCellValue(payDetailGridView.FocusedRowHandle, "ExpenseID").ToString();
            //decimal PayTotal = decimal.Parse(payDetailGridView.GetRowCellValue(payDetailGridView.FocusedRowHandle, "PayTotal").ToString());//已支付总额
            //decimal Budget = decimal.Parse(payDetailGridView.GetRowCellValue(payDetailGridView.FocusedRowHandle, "Budget").ToString());//预算价

            ////更新计划收入项“AdjustPrice调整金额”
            //ExpensesCtrl.UpdateExpenseAdjustAmountData(PayTotal - Budget, expenseId);

            ////更新界面
            //payDetailGridView.SetRowCellValue(payDetailGridView.FocusedRowHandle, "AdjustAmount", PayTotal - Budget);
        //}
        
        /// <summary>
        /// 终结团
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSettlementTourgroup_Click(object sender, EventArgs e)
        {
            //审核状态后不能'增加'、'移除'导游
            TeamStateEnum state = TeamGroupCtrl.GetTourGroupState(btnTeamGroupID.Text);
            if (state == TeamStateEnum.终结)
            {
                MessageBox.Show("此团已经终结！", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            string tourGroupName = "";
            msg.Clear();

            #region 检测当前选择的团状态

            if (string.IsNullOrEmpty(tbTourgroupState.Text) || string.IsNullOrEmpty(btnTeamGroupID.Text))
            {
                btnTeamGroupID.Focus();
                msg.AppendText("没有选中任何团\r\n");
                messageDockPanel.Visibility = DevExpress.XtraBars.Docking.DockVisibility.Visible;
                return;
            }
            else
            {
                tourGroupName = TeamGroupCtrl.GetTeamGroupNameById(btnTeamGroupID.Text);
                if (tourGroupName == "")
                {
                    msg.AppendText("没有选中任何团\r\n");
                    messageDockPanel.Visibility = DevExpress.XtraBars.Docking.DockVisibility.Visible;
                    return;
                }
                else if (EnumHelper.Team_Str2Enum(tbTourgroupState.Text, false) != TeamStateEnum.审核)
                {
                    msg.AppendText("本团还未进行审核，请组团人审核后，再进行结算\r\n");
                    messageDockPanel.Visibility = DevExpress.XtraBars.Docking.DockVisibility.Visible;
                    return;
                }
            }

            #endregion

            #region 检测‘收款’、‘付款’项费用是否平衡

            DataTable dtIncomeItemData = IncomeItemCtrl.GetIncomeItemData(btnTeamGroupID.Text);
            DataTable dtExpenseData = ExpensesCtrl.GetExpenseData(btnTeamGroupID.Text);

            decimal receivedPrice = 0, planPrice = 0, adjustPrice = 0;

            foreach (DataRow dr in dtIncomeItemData.Rows)
            {
                //[PlanPrice] - [ReceivedPrice] - [AdjustPrice]=0
                receivedPrice = dr["ReceivedPrice"] == null ? 0 : decimal.Parse(dr["ReceivedPrice"].ToString());
                planPrice = dr["PlanPrice"] == null ? 0 : decimal.Parse(dr["PlanPrice"].ToString());
                adjustPrice = dr["AdjustPrice"] == null ? 0 : decimal.Parse(dr["AdjustPrice"].ToString());

                if (decimal.Round(planPrice - receivedPrice - adjustPrice,2) != 0)
                {
                    msg.AppendText("收款项中存在‘欠款’不为零，请进行相关处理后再进行结算\r\n");
                    messageDockPanel.Visibility = DevExpress.XtraBars.Docking.DockVisibility.Visible;
                    return;
                }
            }

            decimal budget = 0, applyPayTotal = 0, adjustAmount = 0;

            foreach (DataRow dr in dtExpenseData.Rows)
            {
                //[Budget] - [ApplyPayTotal] - [AdjustAmount]=0
                budget = dr["Budget"] == null ? 0 : decimal.Parse(dr["Budget"].ToString());
                applyPayTotal = dr["ApplyPayTotal"] == null ? 0 : decimal.Parse(dr["ApplyPayTotal"].ToString());
                adjustAmount = dr["AdjustAmount"] == null ? 0 : decimal.Parse(dr["AdjustAmount"].ToString());
                //if (dr["PayStatus"].ToString() == PayStatusEnum.未付.ToString())
                if (decimal.Round(budget - applyPayTotal - adjustAmount,2) != 0)
                {
                    msg.AppendText("付款中存在‘计划金额’与‘已申请总额’和‘调整额’之差不平衡项，请进行相关处理后再进行结算\r\n");
                    messageDockPanel.Visibility = DevExpress.XtraBars.Docking.DockVisibility.Visible;
                    return;
                }
            } 

            #endregion

            //#region 团实际费用计算并写入

            //decimal dRealReceivedPriceTotal = IncomeItemCtrl.GetIncomeItemReceivedPriceTotal(btnTeamGroupID.Text);                              //实际额收入
            //decimal dRealApplyPayTotal = ExpensesCtrl.GetExpenseApplyPayTotal(btnTeamGroupID.Text);                                                       //实际额成本
            //TeamGroupCtrl.UpdateTourGroupReal(btnTeamGroupID.Text, dRealApplyPayTotal, dRealReceivedPriceTotal);
            
            //#endregion

            #region 以上检测通过，终结团
            if (MessageBox.Show(string.Format("确认终结团‘{0}’此操作不可撤销！", tourGroupName), "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                TeamGroupCtrl.UpdateTourGroupState(btnTeamGroupID.Text, TeamStateEnum.终结);//原系统中团的状态只有成行、审核两个状态
                ExpensesCtrl.UpdateExpenseStatusEnd(btnTeamGroupID.Text);
            
                #region 对费用中“支付状态”置成“付清”
                ExpensesCtrl.UpdateExpensePayStatusData(btnTeamGroupID.Text,PayApplyStatusEnum.付清);
                #endregion

                btnTeamGroupID_TextChanged(null, null);

            }
            #endregion


        }
        
        #region 补充摘要
        private void btnModifyIncomeRemark_Click(object sender, EventArgs e)
        {
            if (incomeItemGridView.FocusedRowHandle < 0) return;
            VouchernRemarkForm voucherForm = new VouchernRemarkForm();

            if (voucherForm.ShowDialog(this) == DialogResult.OK)
            {
                string incomeItemId = incomeItemGridView.GetRowCellValue(incomeItemGridView.FocusedRowHandle, "IncomeItemID").ToString();
                string incomeitem = incomeItemGridView.GetRowCellValue(incomeItemGridView.FocusedRowHandle, "IncomeItem").ToString() + " " + voucherForm.tbRemark.Text;
                IncomeItemCtrl.UpdateIncomeItem(incomeitem, incomeItemId);
                //刷新界面
                incomeItemGridView.SetRowCellValue(incomeItemGridView.FocusedRowHandle, "IncomeItem", incomeitem);
            }

        }

        private void btnModifyExpenseRemark_Click(object sender, EventArgs e)
        {
            if (expenseGridView.FocusedRowHandle < 0) return;
            VouchernRemarkForm voucherForm = new VouchernRemarkForm();

            if (voucherForm.ShowDialog(this) == DialogResult.OK)
            {
                string expenseID = expenseGridView.GetRowCellValue(expenseGridView.FocusedRowHandle, "ExpenseID").ToString();
                string serviceName = expenseGridView.GetRowCellValue(expenseGridView.FocusedRowHandle, "ServiceName").ToString() + " " + voucherForm.tbRemark.Text;
                ExpensesCtrl.UpdateExpenseServiceName(serviceName, expenseID);
                //刷新界面
                expenseGridView.SetRowCellValue(expenseGridView.FocusedRowHandle, "ServiceName", serviceName);
            }

        }
        #endregion

        #region 财务调整
        private void btnAddPayment_Click(object sender, EventArgs e)
        {
            if (expenseGridView.FocusedRowHandle < 0) return;

            AddPaymentFinanceForm addform = new AddPaymentFinanceForm();
            if (addform.ShowDialog(this) == DialogResult.OK)
            {
                #region 准备付款申请单和付款详情数据

                string providerId = expenseGridView.GetRowCellValue(expenseGridView.FocusedRowHandle, "ProviderID").ToString();
                ProviderEntity provider = BaseInfoCtrl.GetProviderDataByID(providerId);
                string currentUser = UserInfoCtrl.GetNameByUserName(Thread.CurrentPrincipal.Identity.Name);
                string remark = currentUser + " 财务调整 " + provider.ProviderName + " 费用 " + addform.tbRemark.Text;
                decimal payApply = decimal.Parse(addform.tbPayApply.EditValue.ToString());

                PayApplyEntity payApplyEntity = new PayApplyEntity()
                {
                    //PayApplyID = ,
                    ProviderName = provider.ProviderName,
                    ProviderID = provider.ProviderID,
                    Contact = provider.Contact,
                    Telephone = provider.Telephone,
                    Fax = provider.fax,
                    TotalpaymentG = MoneyHelper.ChMoney(payApply),
                    TotalpaymentL = payApply,
                    Applicants = currentUser,//当前登录者
                    Audit = currentUser,//当前登录者
                    PlanPayTime = DateTime.Today.ToString("yyyy-MM-dd"),//是月结供应商则‘月结’，否则提供拟汇款时间
                    ApplyPayTime = DateTime.Today.ToString("yyyy-MM-dd"),//申请时间
                    PayTime = DateTime.Today.ToString("yyyy-MM-dd"),//财务付款时间
                    PayStatus = PayStatusEnum.已付.ToString(),
                    Remark = remark
                };

                //准备付款详情数据
                PayDetailEntity[] payDetailEntity = new PayDetailEntity[1];

                int expenseId = int.Parse(expenseGridView.GetRowCellValue(expenseGridView.FocusedRowHandle, "ExpenseID").ToString());

                //创建一条付款详情信息——供历史查询
                payDetailEntity[0] = new PayDetailEntity();
                //entity[0].PayApplyID = payApplyId;
                payDetailEntity[0].ExpenseID = expenseId;
                payDetailEntity[0].ApplyPay = payApply;
                payDetailEntity[0].Remark = addform.tbRemark.Text;

                //写入付款单及付款详情数据
                string payApplyId = PayApplyCtrl.CreatePayApplyAndPayDetailData(payApplyEntity, payDetailEntity);

                //更新已申请总额和已支付总额
                ExpensesCtrl.UpdateApplyPayTotal(expenseId,payApply);

                //更新审核成本
                TeamGroupCtrl.UpdateTourGroupBudgeCost(btnTeamGroupID.Text);
                //更新团实际成本
                TeamGroupCtrl.UpdateTourGroupRealCost(btnTeamGroupID.Text);

                //#region 计入流水账
                //AccountManagerEntity entity = new AccountManagerEntity();
                //entity.Date = DateTime.Now.ToString("yyyy-MM-dd");
                //entity.Summary = remark;//摘要
                //entity.Income = 0;
                //entity.Expenditure = payApply; //汇款总额
                //entity.Remark = "";
                //entity.ItemType = 0;
                //entity.ItemID = payApplyId;
                //entity.Voucher = addform.tbRemark.Text;
                //entity.PaymentMethod = "调整";
                //entity.AccountType = AccountTypeEnum.银行.ToString();
                //entity.Transactor = currentUser;
                //AccountManagerCtrl.CreateAccountManagerData(entity);
                //#endregion


                #endregion
                
                //团财务情况统计
                FinanceStatistics();
                //显示各项数据
                financeTab_SelectedPageChanged(financeTab, new DevExpress.XtraTab.TabPageChangedEventArgs(null, financeTab.SelectedTabPage));
            }

        }
        #endregion
    }
}
